﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Shapes;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;

namespace RouteTest
{
    public enum enumNodeRouteType
    {
        Normal,
        Required,
        Avoidance,
    }

    public delegate void delegateNodeMove(object sender, object value);
    public delegate void delegateNodeSelected(object sender, object value);

    public class NodeShape
    {
        public event delegateNodeMove OnNodeMove = null;
        public event delegateNodeSelected OnNodeSelected = null;

        public stNode _Node = new stNode();
        //public enumMode _Mode;
        public Label _Label = new Label();
        private Canvas _Parent;
        private Menu _Menu = new Menu();
        public bool _Selected;
        public bool _LockMove;
        public enumNodeRouteType _RouteType;

        public NodeShape(stNode node, Canvas parent)
        {
            _Parent = parent;

            _Node = node;

            _LockMove = false;

            _Label.Content = _Node.name;
            _Label.Width = 30;
            _Label.Height = 30;

            _Label.BorderThickness = new Thickness(3);
            
            _Label.HorizontalAlignment = HorizontalAlignment.Center;
            _Label.VerticalAlignment = VerticalAlignment.Center;

            Canvas.SetLeft(_Label, _Node.position.X - (_Label.Width / 2));
            Canvas.SetTop(_Label, _Node.position.Y - (_Label.Height / 2));

            _Label.Background = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
            _Label.BorderBrush = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0));

            _Label.MouseLeave += new MouseEventHandler(_Label_MouseLeave);
            _Label.MouseMove += new MouseEventHandler(_Label_MouseMove);
            _Label.MouseUp += new MouseButtonEventHandler(_Label_MouseUp);
            _Label.MouseDown += new MouseButtonEventHandler(_Label_MouseDown);

            _Label.ContextMenu = new ContextMenu();
            MenuItem item1 = new MenuItem();
            item1.Header = "Normal Node";
            item1.IsChecked = true;
            item1.Click += new RoutedEventHandler(item1_Click);
            MenuItem item2 = new MenuItem();
            item2.Header = "Required Node";
            item2.Click += new RoutedEventHandler(item2_Click);
            MenuItem item3 = new MenuItem();
            item3.Header = "Avoidance Node";
            item3.Click += new RoutedEventHandler(item3_Click);
            _Label.ContextMenu.Items.Add(item1);
            _Label.ContextMenu.Items.Add(item2);
            _Label.ContextMenu.Items.Add(item3);

            _Selected = false;
        }

        void _Label_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                if (_Selected)
                    SetUnselected();
                else
                    SetSelected();
            }
        }

        void CheckContextMenu(int index)
        {
            for( int i = 0 ; i<_Label.ContextMenu.Items.Count ; i++)
            {
                ((MenuItem)_Label.ContextMenu.Items[i]).IsChecked = false;
            }
            ((MenuItem)_Label.ContextMenu.Items[index]).IsChecked = true;
        }
        void item3_Click(object sender, RoutedEventArgs e)
        {
            CheckContextMenu(2);
            _RouteType = enumNodeRouteType.Avoidance;
            _Label.Background = new SolidColorBrush(Color.FromArgb(255, 100, 100, 100));
            _Label.Foreground = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
        }

        void item2_Click(object sender, RoutedEventArgs e)
        {
            CheckContextMenu(1);
            _RouteType = enumNodeRouteType.Required;
            _Label.Background = new SolidColorBrush(Color.FromArgb(255, 100, 100, 255));
            _Label.Foreground = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
        }

        void item1_Click(object sender, RoutedEventArgs e)
        {
            CheckContextMenu(0);
            _RouteType = enumNodeRouteType.Normal;
            _Label.Background = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
            _Label.Foreground = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0));
        }

        void _Label_MouseUp(object sender, MouseButtonEventArgs e)
        {
           
        }

        public void ChangeColor(bool select)
        {
            if (select)
            {
                System.Diagnostics.Debug.WriteLine("Node Selected:" + _Node.name);
                _Label.Background = new SolidColorBrush(Color.FromArgb(255, 220, 100, 100));
            }
            else
            {
                System.Diagnostics.Debug.WriteLine("Node Unselected:" + _Node.name);
                switch (_RouteType)
                {
                    case enumNodeRouteType.Normal:
                        _Label.Background = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
                        _Label.Foreground = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0));
                        break;
                    case enumNodeRouteType.Required:
                         _Label.Background = new SolidColorBrush(Color.FromArgb(255, 100, 100, 255));
                        _Label.Foreground = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
                        break;
                    case enumNodeRouteType.Avoidance:
                        _Label.Background = new SolidColorBrush(Color.FromArgb(255, 100, 100, 100));
                        _Label.Foreground = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
                        break;
                }
            }
        }

        public void SetSelected()
        {
            if (OnNodeSelected != null)
            {
                OnNodeSelected(this, null);
            }

            _Selected = true;
            ChangeColor(true);

            System.Diagnostics.Debug.WriteLine("SetSelected. Node ID : "+ _Node.id);
            
        }

        public void SetUnselected()
        {
            _Selected = false;
            ChangeColor(false);
        }

        void _Label_MouseMove(object sender, MouseEventArgs e)
        {
            if (_LockMove) return;

            if (e.LeftButton == MouseButtonState.Pressed)
            {
                System.Diagnostics.Debug.WriteLine("Mouse Move 진입");

                System.Diagnostics.Debug.WriteLine("왼쪽 클릭 후 Mouse Move 1");
                Canvas.SetLeft(_Label, e.GetPosition(_Parent).X - (_Label.Width / 2));
                Canvas.SetTop(_Label, e.GetPosition(_Parent).Y - (_Label.Height / 2));
                
                _Node.position = e.GetPosition(_Parent);

                if (OnNodeMove != null)
                {
                    OnNodeMove(this, (object)_Node.position);
                }

                System.Diagnostics.Debug.WriteLine("왼쪽 클릭 후 Mouse Move 2");
            }
        }

        void _Label_MouseLeave(object sender, MouseEventArgs e)
        {

        }

        public void DrawNode()
        {

        }
    }

    public class NodeShapeList : List<NodeShape>
    {
        public int _StartNodeID;
        public bool _IsStartDrawEdge;
        public Canvas _Parent;

        public NodeShapeList()
        {
        }

        public NodeShapeList(Canvas parent)
        {
            _Parent = parent;
        }

        public void AddNode(NodeShape item)
        {
            this.Add(item);

            _Parent.Children.Add(this[this.Count - 1]._Label);
            item.OnNodeSelected += new delegateNodeSelected(item_OnNodeSelected);
        }

        void item_OnNodeSelected(object sender, object value)
        {
            AllNodeUnselect();
            SelectNode(((NodeShape)sender)._Node.id);
        }

        public void SelectNode(int id)
        {
            for(int i = 0 ; i<this.Count;i++)
            {
                if (this[i]._Node.id == id)
                {
                    this[i]._Selected = true;
                    this[i].ChangeColor(true);
                }
            }
        }

        public bool isSelectedNode()
        {
            foreach (NodeShape node in this)
            {
                if (node._Label.IsMouseOver) return true;
            }
            return false;
        }

        public void AllNodeUnselect()
        {
            for (int i = 0; i < this.Count; i++)
            {
                this[i].SetUnselected();
            }
        }

        public int GetSelectedNodeID()
        {
            foreach (NodeShape node in this)
            {
                if (node._Selected)
                    return node._Node.id;
            }
            return -1;
        }

        public int IsOnMouseOver()
        {
            foreach (NodeShape node in this)
            {
                if (node._Label.IsMouseOver)
                    return node._Node.id;
            }
            return -1;
        }

        public void LockNodeMove()
        {
            for (int i = 0; i < this.Count; i++)
            {
                this[i]._LockMove = true;
            }
        }
        public void UnlockNodeMove()
        {
            for (int i = 0; i < this.Count; i++)
            {
                this[i]._LockMove = false;
            }
        }

        public int HasRequiredNode()
        {
            for (int i = 0; i < this.Count; i++)
            {
                if(this[i]._RouteType== enumNodeRouteType.Required)
                    return i;
            }

            return -1;
        }
    }
}
